package com.seed.dev.web;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.seed.application.A;
import com.seed.core.configuration.AppConfiguration;
import com.seed.core.pojo.R;
import com.seed.util.AppLoadKit;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.nio.charset.Charset;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;

@RestController
@RequestMapping("/app")
public class AppController {
    @Value("${seed.path:}")
    private String path;

    @Value("${seed.preview:}")
    private String preview;

    @GetMapping("list")
    public R<List<AppConfiguration>> list() {
        String owner = getOwner();
        String realPath = StrUtil.isBlank(owner) ? path : path + File.separator + owner;
        File folder = new File(realPath);
        File[] files = folder.listFiles();
        if(files == null || files.length == 0) return R.data(Collections.emptyList());

        List<AppConfiguration> ret = Stream.of(files)
            .filter(f -> {
                String suffix = FileUtil.getSuffix(f);
                return suffix != null && suffix.equals("json");
            }).map(f -> {
                AppConfiguration app = AppLoadKit.load(f);
                AppConfiguration item = new AppConfiguration();
                item.setName(app.getName());
                item.setOwner(app.getOwner());
                item.setLabel(app.getLabel());
                item.setComment(app.getComment());

                return item;
            }).toList();

        return R.data(ret);
    }

    @PostMapping("create")
    public R<String> create(@RequestBody AppConfiguration app) {
        String name = app.getName();
        if(StrUtil.isBlank(name)) return R.error("名称不能为空");

        File file = getAppFile(name);
        if(file.exists()) return R.error(String.format("应用【%s】已存在", name));

        String owner = getOwner();
        if(StrUtil.isNotBlank(owner)) app.setOwner(owner);
        saveToFile(app, file);

        return R.ok("保存成功");
    }

    @PutMapping("update")
    public R<String> update(@RequestBody AppConfiguration app) {
        String name = app.getName();
        if(StrUtil.isBlank(name)) return R.error("名称不能为空");

        File file = getAppFile(name);
        saveToFile(app, file);

        return R.ok("更新成功");
    }

    @GetMapping("detail")
    public R<AppConfiguration> detail(String name) {
        File file = getAppFile(name);
        if(file.exists()) return R.data(AppLoadKit.load(file));

//        file = new File(path + File.separator + name + ".yml");
//        if(file.exists()) return R.data(AppUtil.load(file));
//
//        file = new File(path + File.separator + name + ".yaml");
//        if(file.exists()) return R.data(AppUtil.load(file));

        return R.error(String.format("应用【%s】不存在", name));
    }

    /**
     * 删除应用
     * 1. 删除数据库，包括主应用服务、主应用服务租户、微服务以及微服务租户库
     * 2. 清理数据库连接对象
     * 3. 删除硬盘上的应用配置文件
     * 4. 清除内存里的应用对象
     * @param name 应用名称
     * @return
     */
    @DeleteMapping("remove")
    public R<String> remove(String name) {
        File file = getAppFile(name);
        if(!file.exists()) return R.error(String.format("应用【%s】不存在", name));

//        String content = FileUtil.readString(file, Charset.defaultCharset());
//        AppConfiguration app = JSONUtil.toBean(content, AppConfiguration.class);
        // 删除数据库 TODO 暂时不做，可以手动删除
        // 清理数据库连接对象 TODO 暂时不做，重启后会自动消失
        FileUtil.del(file); // 删除硬盘上的应用配置文件
        A.removeApp(getOwner(), name); // 清除内存里的应用对象

        return R.ok("删除成功");
    }

    @GetMapping("preview")
    public R<String> preview() {
        return R.data(preview);
    }

    private void saveToFile(AppConfiguration app, File file) {
        FileUtil.writeString(JSONUtil.parse(app).toJSONString(2), file, Charset.defaultCharset());
    }

    private File getAppFile(String name) {
        String owner = getOwner();
        String ownerPath = StrUtil.isBlank(owner) ? "" : File.separator + owner;
        return new File(path + ownerPath + File.separator + name + ".json");
    }

    private String getOwner() {
        return StpUtil.isLogin() ? (String) StpUtil.getLoginId() : null;
    }
}
